Imports Magic

Public Class ctrReflexive
#Region "Collapse and Expand"
    Private Collapsed As Boolean = False
    Private CollapsedHeight As Integer = 32
    Private ExpandedHeight As Integer = 0
    Private Sub tsbCollapse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCollapse.Click
        Me.AutoSize = Collapsed
        If Collapsed Then
            btnCollapse.BackgroundImage = My.Resources.Collapse_large
            Me.Height = ExpandedHeight
        Else
            btnCollapse.BackgroundImage = My.Resources.Expand_large
            Me.Height = CollapsedHeight
        End If
        Collapsed = Not Collapsed
    End Sub
    Public Sub FinalizeHeight()
        ExpandedHeight = Me.Height
    End Sub
#End Region
    Public ValuesArray As Array
    Dim Fields As Core.Xpe.Field
    Dim vControls() As Control
    Dim FourCC As String
    Public Event ValueChanged(ByVal sender As ctrReflexive)

    Sub New(ByVal vArray As Array, ByVal vField As Core.Xpe.Field, ByVal TagType As String)

        'ts.SetToolTip(btnCollapse, "Add New Chunk")
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        Me.Height = 32
        Me.SuspendLayout()
        pnlControls.SuspendLayout()

        ' Add any initialization after the InitializeComponent() call.
        Dim ts As New ToolTip
        ts.SetToolTip(btnAddChunk, "Add Chunk")
        ts.SetToolTip(btnDeleteChunk, "Delete Chunk")
        ts.SetToolTip(btnCopy, "Copy Chunk")
        ts.SetToolTip(btnPaste, "Paste Chunk")
        Fields = vField
        ValuesArray = vArray
        FourCC = TagType
        Me.lblName.Text = Fields.Name

        ReDim vControls(Fields.Children.Length - 1)
        For x As Integer = 0 To Fields.Children.Length - 1
            Select Case Fields.Children(x).Type
                Case Magic.Core.Xpe.FieldType.Float1, Magic.Core.Xpe.FieldType.Int1, Magic.Core.Xpe.FieldType.Short1, Magic.Core.Xpe.FieldType.Char, Magic.Core.Xpe.FieldType.String
                    Dim nControl As ctrValue1 = New ctrValue1
                    nControl.lblName.Text = Fields.Children(x).Name
                    AddHandler nControl.ValueChanged, AddressOf Value1Changed
                    vControls(x) = nControl
                Case Magic.Core.Xpe.FieldType.Float2, Magic.Core.Xpe.FieldType.Int2, Magic.Core.Xpe.FieldType.Short2
                    Dim nControl As ctrValue2 = New ctrValue2
                    nControl.lblName.Text = Fields.Children(x).Name
                    AddHandler nControl.ValueChanged, AddressOf Value2Changed
                    vControls(x) = nControl
                Case Magic.Core.Xpe.FieldType.Float3, Magic.Core.Xpe.FieldType.Int3, Magic.Core.Xpe.FieldType.Short3
                    Dim nControl As ctrValue3 = New ctrValue3
                    nControl.lblName.Text = Fields.Children(x).Name
                    AddHandler nControl.ValueChanged, AddressOf Value3Changed
                    vControls(x) = nControl
                Case Magic.Core.Xpe.FieldType.Block
                    Dim BlockArray As Array
                    If vArray.GetLength(0) > 0 Then
                        BlockArray = vArray(0, x)
                    Else
                        BlockArray = Magic.Core.Xpe.DefaultValue(Core.Xpe.FieldType.Block, 0, vField.Children.Count)
                    End If
                    'If BlockArray.GetLength(0) > 0 Then
                    Dim nControl As ctrReflexive = New ctrReflexive(BlockArray, Fields.Children(x), FourCC)
                    vControls(x) = nControl
                    AddHandler nControl.ValueChanged, AddressOf ReflexiveChanged
                    'End If
                Case Core.Xpe.FieldType.Prestructure

                    If FourCC = "ustr" Then
                        Dim nControl As New ctrValue1
                        nControl.SuspendLayout()
                        nControl.Unicode = True
                        nControl.lblName.Text = vField.Children(x).Name
                        AddHandler nControl.ValueChanged, AddressOf Value1Changed
                        vControls(x) = nControl
                    ElseIf FourCC = "str#" Then
                        Dim nControl As New ctrValue1
                        nControl.SuspendLayout()
                        nControl.Unicode = False
                        nControl.lblName.Text = vField.Children(x).Name
                        AddHandler nControl.ValueChanged, AddressOf Value1Changed
                        vControls(x) = nControl
                    End If
                Case Core.Xpe.FieldType.DWordFlags, Core.Xpe.FieldType.WordFlags, Core.Xpe.FieldType.CharFlags
                    If vField.Children(x).Arguments.Length > 0 Then
                        Dim nControl As ctrFlags = New ctrFlags
                        nControl.lblName.Text = vField.Children(x).Name
                        AddHandler nControl.ValueChanged, AddressOf FlagChanged
                        nControl.cList.Items.AddRange(vField.Children(x).Arguments)
                        If vField.Children(x).Arguments.Length > 10 Then
                            nControl.Height = 10 * 15 + 7
                        Else
                            nControl.Height = vField.Children(x).Arguments.Length * 15 + 7
                        End If
                        vControls(x) = nControl
                    End If
                Case Core.Xpe.FieldType.Float4, Core.Xpe.FieldType.Int4, Core.Xpe.FieldType.Short4
                    Dim nControl As ctrValue4 = New ctrValue4
                    nControl.SuspendLayout()
                    nControl.lblName.Text = vField.Children(x).Name
                    AddHandler nControl.ValueChanged, AddressOf Value4Changed
                    vControls(x) = nControl
                Case Core.Xpe.FieldType.Enum
                    Dim nControl As ctrEnum = New ctrEnum
                    nControl.SuspendLayout()
                    nControl.lblName.Text = vField.Children(x).Name
                    nControl.EnumValue.Items.AddRange(vField.Children(x).Arguments)
                    AddHandler nControl.ValueChanged, AddressOf EnumChanged
                    vControls(x) = nControl
                Case Core.Xpe.FieldType.TagReference
                    Dim nControl As New ctrReference
                    nControl.SuspendLayout()
                    nControl.lblName.Text = vField.Children(x).Name
                    AddHandler nControl.ValueChanged, AddressOf ReferenceChanged
                    vControls(x) = nControl
            End Select
            If Not IsNothing(vControls(x)) Then
                pnlControls.Controls.Add(vControls(x))
                'vControls(x).Dock = DockStyle.Top
                'vControls(x).BringToFront()
                Me.Height += vControls(x).Height + 6
                vControls(x).Tag = x
            End If
        Next
        FinalizeHeight()

        'Edit ComboBox Names 
        cmbBlockIndex.Items.Clear()
        For x As Integer = 0 To vArray.GetLength(0) - 1
            Dim cName As String = x
            For y As Integer = 0 To Fields.Children.Length - 1
                If InStr(Fields.Children(y).Name, "^") Then
                    Select Case Fields.Children(y).Type
                        Case Magic.Core.Xpe.FieldType.TagReference, Magic.Core.Xpe.FieldType.SelfReference
                            cName = magicMap.Library.GetName(ValuesArray.GetValue(x, y)).Substring(magicMap.Library.GetName(ValuesArray.GetValue(x, y)).LastIndexOf("\") + 1).TrimEnd(Chr(0))
                        Case Else
                            cName = ValuesArray.GetValue(x, y)
                    End Select
                End If
            Next
            If cName = String.Empty Then cName = x
            Me.cmbBlockIndex.Items.Add(cName)
        Next
        For x As Integer = 0 To vControls.Count - 1
            If Not IsNothing(vControls(x)) Then
                If vControls(x).Width >= Me.Width Then
                    Me.Width = vControls(x).Width + 9
                End If
            End If
        Next
        If vArray.GetLength(0) > 0 Then cmbBlockIndex.SelectedIndex = 0
        'pnlControls.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
        'pnlControls.AutoSize = True
        'Me.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
        'Me.AutoSize = True
        pnlControls.ResumeLayout()
        Me.ResumeLayout()

    End Sub
    Public Sub UpdateArray(ByVal vArray As Array)
        ValuesArray = vArray
        cmbBlockIndex.Items.Clear()
        If vArray.GetLength(0) > 0 Then
            For x As Integer = 0 To vArray.GetLength(0) - 1
                Dim cName As String = x
                For y As Integer = 0 To Fields.Children.Length - 1
                    If InStr(Fields.Children(y).Name, "^") Then
                        Select Case Fields.Children(y).Type
                            Case Magic.Core.Xpe.FieldType.TagReference, Magic.Core.Xpe.FieldType.SelfReference
                                cName = magicMap.Library.GetName(ValuesArray.GetValue(x, y)).Substring(magicMap.Library.GetName(ValuesArray.GetValue(x, y)).LastIndexOf("\") + 1).TrimEnd(Chr(0))
                            Case Else
                                cName = ValuesArray.GetValue(x, y)
                        End Select
                    End If
                Next
                If cName = String.Empty Then cName = x
                Me.cmbBlockIndex.Items.Add(cName)
            Next
            cmbBlockIndex.SelectedIndex = 0
        End If
    End Sub
    Private Sub tscBlockIndex_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmbBlockIndex.SelectedIndexChanged
        For x As Integer = 0 To Fields.Children.Length - 1
            If Not IsNothing(vControls(x)) Then
                Select Case Fields.Children(x).Type
                    Case Magic.Core.Xpe.FieldType.Prestructure
                        If FourCC = "ustr" Or FourCC = "str#" Then
                            Dim nControl As ctrValue1 = vControls(x)
                            nControl.UserDidIt = False
                            If nControl.Unicode = True Then
                                nControl.txtValue.Text = System.Text.UnicodeEncoding.Unicode.GetString(ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x))
                            Else
                                nControl.txtValue.Text = System.Text.ASCIIEncoding.ASCII.GetString(ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x))
                            End If
                            nControl.UserDidIt = True
                        End If
                    Case Magic.Core.Xpe.FieldType.Float1, Magic.Core.Xpe.FieldType.Int1, Magic.Core.Xpe.FieldType.Short1, Magic.Core.Xpe.FieldType.Char, Magic.Core.Xpe.FieldType.String
                        Dim nControl As ctrValue1 = vControls(x)
                        nControl.UserDidIt = False
                        nControl.txtValue.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)
                        nControl.UserDidIt = True
                    Case Magic.Core.Xpe.FieldType.Float2, Magic.Core.Xpe.FieldType.Int2, Magic.Core.Xpe.FieldType.Short2
                        Dim nControl As ctrValue2 = vControls(x)
                        nControl.UserDidIt = False
                        nControl.txtValue.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(0)
                        nControl.txtValue2.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(1)
                        nControl.UserDidIt = True
                    Case Magic.Core.Xpe.FieldType.Float3, Magic.Core.Xpe.FieldType.Int3, Magic.Core.Xpe.FieldType.Short3
                        Dim nControl As ctrValue3 = vControls(x)
                        nControl.UserDidIt = False
                        nControl.txtValue.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(0)
                        nControl.txtValue2.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(1)
                        nControl.txtValue3.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(2)
                        nControl.UserDidIt = True
                    Case Magic.Core.Xpe.FieldType.Block
                        Dim nControl As ctrReflexive = vControls(x)
                        nControl.UpdateArray(ValuesArray(cmbBlockIndex.SelectedIndex, x))
                    Case Core.Xpe.FieldType.DWordFlags, Core.Xpe.FieldType.WordFlags, Core.Xpe.FieldType.CharFlags
                        Dim nControl As ctrFlags = vControls(x)
                        nControl.bMask.Value = CInt(ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x))
                        nControl.SetItems()
                    Case Core.Xpe.FieldType.Float4, Core.Xpe.FieldType.Int4, Core.Xpe.FieldType.Short4
                        Dim nControl As ctrValue4 = vControls(x)
                        nControl.UserDidIt = False
                        nControl.txtValue.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(0)
                        nControl.txtValue2.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(1)
                        nControl.txtValue3.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(2)
                        nControl.txtValue4.Text = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)(3)
                        nControl.UserDidIt = True
                    Case Core.Xpe.FieldType.Enum
                        Dim nControl As ctrEnum = vControls(x)
                        nControl.UserDidIt = False
                        nControl.EnumValue.SelectedIndex = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)
                        nControl.UserDidIt = True
                    Case Core.Xpe.FieldType.TagReference
                        Dim nControl As ctrReference = vControls(x)
                        nControl.UserDidIt = False
                        If ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x) > -1 Then
                            nControl.txtTag.Text = magicMap.Library(ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, x)).Name.Replace(appSettings.XboxTagFolder & "\", "")
                        Else
                            nControl.txtTag.Text = "<none>"
                        End If
                        nControl.UserDidIt = True
                End Select
            End If
        Next
    End Sub
    Sub Value1Changed(ByVal sender As ctrValue1)

        Select Case Fields.Children(CInt(sender.Tag)).Type
            Case Core.Xpe.FieldType.Prestructure
                If FourCC = "ustr" Or FourCC = "str#" Then
                    If sender.Unicode = True Then
                        ValuesArray.SetValue(System.Text.UnicodeEncoding.Unicode.GetBytes(sender.txtValue.Text & Chr(0)), cmbBlockIndex.SelectedIndex, sender.Tag)
                    Else
                        ValuesArray.SetValue(System.Text.ASCIIEncoding.ASCII.GetBytes(sender.txtValue.Text & Chr(0)), cmbBlockIndex.SelectedIndex, sender.Tag)
                    End If
                End If
            Case Else
                ValuesArray.SetValue(sender.txtValue.Text, cmbBlockIndex.SelectedIndex, sender.Tag)
        End Select

        If InStr(sender.lblName.Text, "^") Then
            cmbBlockIndex.Items(cmbBlockIndex.SelectedIndex) = sender.txtValue.Text
        End If
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub Value2Changed(ByVal sender As ctrValue2)
        Dim tmpArray As Array = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, sender.Tag)
        tmpArray(0) = sender.txtValue.Text
        tmpArray(1) = sender.txtValue2.Text
        ValuesArray.SetValue(tmpArray, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub Value3Changed(ByVal sender As ctrValue3)
        Dim tmpArray As Array = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, sender.Tag)
        tmpArray(0) = sender.txtValue.Text
        tmpArray(1) = sender.txtValue2.Text
        tmpArray(2) = sender.txtValue3.Text
        ValuesArray.SetValue(tmpArray, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub Value4Changed(ByVal sender As ctrValue4)
        Dim tmpArray As Array = ValuesArray.GetValue(cmbBlockIndex.SelectedIndex, sender.Tag)
        tmpArray(0) = sender.txtValue.Text
        tmpArray(1) = sender.txtValue2.Text
        tmpArray(2) = sender.txtValue3.Text
        tmpArray(3) = sender.txtValue4.Text
        ValuesArray.SetValue(tmpArray, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub EnumChanged(ByVal sender As ctrEnum)
        ValuesArray.SetValue(sender.EnumValue.SelectedIndex, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub FlagChanged(ByVal sender As ctrFlags)
        ValuesArray.SetValue(sender.bMask.Value, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub ReferenceChanged(ByVal sender As ctrReference)
        Dim tagDetail(1) As String
        tagDetail(0) = sender.txtTag.Text.Replace(System.IO.Path.GetExtension(sender.txtTag.Text), "")
        tagDetail(1) = cxpe.FromExtension(System.IO.Path.GetExtension(sender.txtTag.Text).Replace(".", "")).FourCC
        Dim tIndex As Integer = magicMap.Library.GetDependencyTag(tagDetail(0), tagDetail(1), appSettings.XboxTagFolder, IIf(tagDetail(1) = "sbsp", True, False), appSettings.CETagFolder)
        ValuesArray.SetValue(tIndex, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Sub ReflexiveChanged(ByVal sender As ctrReflexive)
        ValuesArray.SetValue(sender.ValuesArray, cmbBlockIndex.SelectedIndex, sender.Tag)
        RaiseEvent ValueChanged(Me)
    End Sub
    Private Sub tsAddChunk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddChunk.Click
        ValuesArray = Fields.AddBlock(ValuesArray, -1) 'cmbBlockIndex.SelectedIndex)
        cmbBlockIndex.Items.Clear()
        For x As Integer = 0 To ValuesArray.GetLength(0) - 1
            Dim cName As String = x
            For y As Integer = 0 To Fields.Children.Length - 1
                If InStr(Fields.Children(y).Name, "^") Then
                    Select Case Fields.Children(y).Type
                        Case Magic.Core.Xpe.FieldType.TagReference, Magic.Core.Xpe.FieldType.SelfReference
                            cName = magicMap.Library.GetName(ValuesArray.GetValue(x, y)).Substring(magicMap.Library.GetName(ValuesArray.GetValue(x, y)).LastIndexOf("\") + 1).TrimEnd(Chr(0))
                        Case Else
                            cName = ValuesArray.GetValue(x, y)
                    End Select
                End If
            Next
            If cName = String.Empty Then cName = x
            Me.cmbBlockIndex.Items.Add(cName)
        Next
        RaiseEvent ValueChanged(Me)
    End Sub

    Private Sub tsDeleteChunk_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDeleteChunk.Click
        ValuesArray = Fields.DeleteBlock(ValuesArray, cmbBlockIndex.SelectedIndex)
        cmbBlockIndex.Items.Clear()
        For x As Integer = 0 To ValuesArray.GetLength(0) - 1
            Dim cName As String = x
            For y As Integer = 0 To Fields.Children.Length - 1
                If InStr(Fields.Children(y).Name, "^") Then
                    Select Case Fields.Children(y).Type
                        Case Magic.Core.Xpe.FieldType.TagReference, Magic.Core.Xpe.FieldType.SelfReference
                            cName = magicMap.Library.GetName(ValuesArray.GetValue(x, y)).Substring(magicMap.Library.GetName(ValuesArray.GetValue(x, y)).LastIndexOf("\") + 1).TrimEnd(Chr(0))
                        Case Else
                            cName = ValuesArray.GetValue(x, y)
                    End Select
                End If
            Next
            If cName = String.Empty Then cName = x
            Me.cmbBlockIndex.Items.Add(cName)
        Next
        RaiseEvent ValueChanged(Me)
    End Sub


    Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblName.Click

    End Sub

    Private Sub btnCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopy.Click
        ' Fields.Name 
        Dim copyObjects(Fields.Children.Count - 1) As Object
        For x As Integer = 0 To copyObjects.Count - 1
            copyObjects(x) = ValuesArray(cmbBlockIndex.SelectedIndex, x)
        Next
        Clipboard.SetData(Fields.Name, copyObjects)

    End Sub

    Private Sub btnPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPaste.Click
        If Clipboard.ContainsData(Fields.Name) Then
            Dim copyObjects() As Object = Clipboard.GetData(Fields.Name)

            ValuesArray = Fields.AddBlock(ValuesArray, -1) 'cmbBlockIndex.SelectedIndex)

            For x As Integer = 0 To copyObjects.Count - 1
                ValuesArray.SetValue(copyObjects(x), ValuesArray.GetLength(0) - 1, x)
            Next

            cmbBlockIndex.Items.Clear()
            For x As Integer = 0 To ValuesArray.GetLength(0) - 1
                Dim cName As String = x
                For y As Integer = 0 To Fields.Children.Length - 1
                    If InStr(Fields.Children(y).Name, "^") Then
                        Select Case Fields.Children(y).Type
                            Case Magic.Core.Xpe.FieldType.TagReference, Magic.Core.Xpe.FieldType.SelfReference
                                cName = magicMap.Library.GetName(ValuesArray.GetValue(x, y)).Substring(magicMap.Library.GetName(ValuesArray.GetValue(x, y)).LastIndexOf("\") + 1).TrimEnd(Chr(0))
                            Case Else
                                cName = ValuesArray.GetValue(x, y)
                        End Select
                    End If
                Next
                If cName = String.Empty Then cName = x
                Me.cmbBlockIndex.Items.Add(cName)
            Next
            RaiseEvent ValueChanged(Me)
        End If
    End Sub
End Class
